import * as React from 'react'
import barImage from './image/arrowright.png'
import successImage from './image/success.png'
import './index.less'
interface ReactSimpleVerifyProps {
  width?: number
  height: number
  borderColor?: string
  bgColor: string
  borderRadius: number
  tips: string
  bandTips: string
  barBackground: string
  movedColor: string
  successTips: string
  successIcon: string
  onSuccess: () => void
}

interface ReactSimpleVerifyState {
  isMouseEnter: boolean
  myWidth: number
  diff: number
}

export default class ReactSimpleVerify extends React.Component<ReactSimpleVerifyProps, ReactSimpleVerifyState> {
  /**
   * 默认参数
   */
  static defaultProps = {
    width: undefined,
    height: 36,
    borderColor: '#E4E4E4',
    bgColor: '#f9f9f9',
    borderRadius: 4,
    tips: '请按住滑块，拖动到最右边',
    bandTips: '失败次数过多，请稍后再试',
    barBackground: `url(${barImage})`,
    movedColor: '#37DA90',
    successTips: '验证通过',
    successIcon: successImage,
  }

  /**
   * 初始数据
   */
  /** x */
  private x1 = 0
  private x2 = 0
  private BTNWIDTH = 50
  /** 最大失败次数 */
  // private MAXRETRYNUM = 8
  /** 已失败次数 */
  // private RETRYNUM = 0
  /** 禁止使用 */
  // private isBandUse = false
  /** 鼠标是否按下 */
  private isMousedown = false
  /** 是否已经成功 */
  private isSuccess = false
  /** 最大滑动距离 */
  private max = this.props.width === undefined ? 0 : this.props.width - this.BTNWIDTH
  /** 盒子样式 */
  private style = {
    width: this.props.width === undefined ? '100%' : this.props.width,
    height: this.props.height,
    border: `${this.props.borderColor} 1px solid`,
    backgroundColor: this.props.bgColor,
    borderRadius: this.props.borderRadius,
  }
  /** 滑条盒子样式 */
  private slideBoxStyle = {
    borderRadius: this.props.borderRadius,
  }
  constructor(props: ReactSimpleVerifyProps) {
    super(props)
    this.state = {
      /** 是否滑入 */
      isMouseEnter: false,
      /** 滑动距离 */
      diff: 0,
      myWidth: 0,
    }
  }

  /**
   * 绑定事件
   */
  public componentDidMount() {
    document.querySelector('.simple-verify')?.addEventListener('touchstart', this.touchDownPoint.bind(this))
    document.body.addEventListener('touchmove', this.mousemove.bind(this))
    document.body.addEventListener('touchend', this.mouseup.bind(this))
    document.body.addEventListener('mousemove', this.mousemove.bind(this))
    document.body.addEventListener('mouseup', this.mouseup.bind(this))
    if (this.props.width === undefined) {
      const myWidth = document.querySelector('.simple-verify')!.clientWidth
      if (myWidth > 0) {
        this.setState({
          myWidth: myWidth,
        })
        this.max = myWidth - this.BTNWIDTH
      }
    }
  }

  /**
   * 移除事件
   */
  public componentWillUnmount() {
    document.querySelector('.simple-verify')?.removeEventListener('touchstart', this.touchDownPoint.bind(this))
    document.body.removeEventListener('touchmove', this.mousemove.bind(this))
    document.body.removeEventListener('touchend', this.mouseup.bind(this))
    document.body.removeEventListener('mousemove', this.mousemove.bind(this))
    document.body.removeEventListener('mouseup', this.mouseup.bind(this))
  }

  /**
   * 鼠标移入
   */
  private mouseenter() {
    if (this.isSuccess) {
      return
    }
    this.setState({
      isMouseEnter: true,
    })
  }

  /**
   * 鼠标离开
   */
  private mouseleave() {
    if (this.isSuccess || this.isMousedown) {
      return
    }
    this.setState({
      isMouseEnter: false,
    })
  }

  /**
   * 鼠标按下
   */
  private mousedown(e: any) {
    if (this.isSuccess) {
      return
    }
    this.x1 = e.nativeEvent.x || e.touches[0].clientX
    this.isMousedown = true
  }
  private touchDownPoint(e: any) {
    if (this.isSuccess) {
      return
    }
    this.x1 = e.touches[0].clientX
    this.isMousedown = true
    this.setState({
      isMouseEnter: true,
    })
  }
  /**
   * 鼠标移动
   */
  private mousemove(e: any) {
    if (!this.isMousedown || this.isSuccess) {
      return
    }
    e.preventDefault()
    e.stopPropagation()
    this.x2 = e.x || e.touches[0].clientX
    let diff = this.x2 - this.x1
    if (diff < 0) {
      diff = 0
    }
    if (diff >= this.max) {
      diff = this.max
      this.isSuccess = true
      this.props.onSuccess && this.props.onSuccess()
    }
    this.setState({
      diff,
    })
  }

  /**
   * 鼠标松开
   */
  private mouseup(e: any) {
    if (this.isSuccess) {
      return
    }
    this.isMousedown = false
    this.setState({
      isMouseEnter: false,
      diff: 0,
    })
  }

  /**
   * 重置
   */
  public reset() {
    this.isSuccess = false
    this.setState({
      diff: 0,
    })
    this.isMousedown = false
    this.setState({
      isMouseEnter: false,
    })
  }

  public render() {
    /** 滑条样式 */
    const slideStyle = {
      borderRadius: this.props.borderRadius,
      background: this.isMousedown ? this.props.movedColor : '',
      left: 50 - (this.props.width === undefined ? this.state.myWidth : this.props.width),
      opacity: this.state.isMouseEnter ? 1 : 0,
      transitionDuration: !this.state.isMouseEnter || !this.isMousedown ? '.3s' : '0s',
      transform: `translateX(${this.state.diff}px)`,
    }
    /** 滑块样式 */
    const barStyle = {
      backgroundImage: !this.isSuccess ? this.props.barBackground : `url(${successImage})`,
      backgroundSize: !this.isSuccess ? `22px 20px` : `20px 20px`,
      transitionDuration: !this.state.isMouseEnter || !this.isMousedown ? '.3s' : '0s',
      transform: `translateX(${this.state.diff}px)`,
    }
    /** 成功文本样式 */
    const textStyle = {
      opacity: this.isSuccess ? 1 : 0,
      transitionDuration: !this.state.isMouseEnter || !this.isMousedown ? '.3s' : '0s',
    }
    return (
      <div style={this.style} className="simple-verify">
        <div style={this.slideBoxStyle} className="verify-box">
          <div style={slideStyle} className="veriry-slide" />
        </div>
        <div className="verify-tips" style={{ display: this.isSuccess ? 'none' : '' }}>
          {this.props.tips}
        </div>
        <div
          className="verify-bar"
          onMouseEnter={this.mouseenter.bind(this)}
          onTouchStart={this.touchDownPoint.bind(this)}
          onMouseLeave={this.mouseleave.bind(this)}
          onTouchEnd={this.mouseleave.bind(this)}
          onMouseDown={this.mousedown.bind(this)}
        >
          <div style={barStyle} className="slider-verify-icon" />
        </div>
        <div style={textStyle} className="verify-success-tips">
          {this.props.successTips}
        </div>
      </div>
    )
  }
}
